﻿namespace StreetCrime
{
    using System;
    using Serialization;
    using WP7Contrib.Common;

    [Serializer(typeof(StreetLevelCrimeLocation))]
    public sealed class StreetLevelCrimeLocation : BaseModel, ISerializeObject, IEquatable<StreetLevelCrimeLocation>
    {
        private double latitude;

        private double longitude;

        private StreetLevelCrimeStreet street;

        public StreetLevelCrimeLocation()
        {
        }

        public object[] Serialize(object target)
        {
            var location = (StreetLevelCrimeLocation)target;
            return new object[] { location.Latitude,
                                  location.Longitude,
                                  location.Street};
        }

        public object Deserialize(object[] data)
        {
            var location = new StreetLevelCrimeLocation
            {
                Latitude = (double)data[0],
                Longitude = (double)data[1],
                Street = (StreetLevelCrimeStreet)data[2]
            };

            return location;
        }

        public double Latitude
        {
            get
            {
                return this.latitude;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.latitude, value, () => this.Latitude);
            }
        }

        public double Longitude
        {
            get
            {
                return this.longitude;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.longitude, value, () => this.Longitude);
            }
        }

        public StreetLevelCrimeStreet Street
        {
            get
            {
                return this.street;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.street, value, () => this.Street);
            }
        }

        public static bool operator ==(StreetLevelCrimeLocation slcl1, StreetLevelCrimeLocation slcl2)
        {
            return Equals(slcl1, slcl2);
        }

        public static bool operator !=(StreetLevelCrimeLocation slcl1, StreetLevelCrimeLocation slcl2)
        {
            return !Equals(slcl1, slcl2);
        }

        public bool Equals(StreetLevelCrimeLocation location)
        {
            if (ReferenceEquals(null, location))
            {
                return false;
            }

            if (this.Latitude != location.Latitude)
            {
                return false;
            }

            if (this.Longitude != location.Longitude)
            {
                return false;
            }

            if (this.Street != location.Street)
            {
                return false;
            }

            return true;
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj))
            {
                return false;
            }

            return obj is StreetLevelCrimeLocation && this.Equals((StreetLevelCrimeLocation)obj);
        }

        public override int GetHashCode()
        {
            return this.CombineHashCodes(this.Latitude, this.Longitude, this.Street);
        }
    }
}